package com.bsy.network.manager

import HeaderInterceptor
import android.util.Log
import com.bsy.framework.helper.AppHelper
import com.bsy.framework.utils.NetworkUtil
import com.bsy.network.adapter.BooleanDefaultAdapter
import com.bsy.network.adapter.CollectionDefaultTypeAdapterFactory
import com.bsy.network.adapter.DoubleDefaultAdapter
import com.bsy.network.adapter.GsonDConverterFactory
import com.bsy.network.adapter.IntegerDefaultAdapter
import com.bsy.network.adapter.LongDefaultAdapter
import com.bsy.network.adapter.StringNullAdapter
import com.bsy.network.error.ERROR
import com.bsy.network.error.NoNetWorkException
import com.bsy.network.interceptor.BaseUrlInterceptor
import com.google.gson.FieldNamingPolicy
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.internal.ConstructorConstructor
import com.google.gson.internal.Excluder
import com.hjq.gson.factory.element.ReflectiveTypeAdapterFactory
import okhttp3.ConnectionPool
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import java.util.concurrent.TimeUnit

/**
 * @author Sincerity
 * @date   2023/2/23 21:29
 * @desc  网络请求管理类
 */
object HttpManager {
    private val mRetrofit: Retrofit

    init {
        mRetrofit = Retrofit.Builder()
            .client(initOkHttpClient(10))
            .baseUrl(AppHelper.getBaseUrl())
            .addConverterFactory(GsonDConverterFactory.create(buildGson()))
            .build()
    }

    /**
     * 获取 apiService
     */
    fun <T> create(apiService: Class<T>): T {
        return mRetrofit.create(apiService)
    }

    /**
     * 初始化OkHttp
     */
    fun initOkHttpClient(time: Long): OkHttpClient {
        val build = OkHttpClient.Builder()
            .connectTimeout(time, TimeUnit.SECONDS)
            .writeTimeout(time, TimeUnit.SECONDS)
            .readTimeout(time, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
            .connectionPool(ConnectionPool())
            .addInterceptor(BaseUrlInterceptor())
            .addInterceptor(HeaderInterceptor())
        //日志拦截器
        val logInterceptor = HttpLoggingInterceptor { message: String ->
            Log.i("okhttp", "data:$message")
        }
        if (AppHelper.isDebug())
            logInterceptor.level = HttpLoggingInterceptor.Level.BODY
        else
            logInterceptor.level = HttpLoggingInterceptor.Level.NONE


        build.addInterceptor(logInterceptor)
        //网络状态拦截
        build.addInterceptor(object : Interceptor {
            override fun intercept(chain: Interceptor.Chain): Response {
                if (NetworkUtil.isConnected(AppHelper.getApplication())) {
                    val request = chain.request()
                    return chain.proceed(request)
                } else {
                    throw NoNetWorkException(ERROR.NETWORD_ERROR)
                }
            }
        })
        return build.build()
    }

    private fun buildGson(): Gson {
        return GsonBuilder()
            .registerTypeAdapter(Boolean::class.java, BooleanDefaultAdapter())
            .registerTypeAdapter(Int::class.java, IntegerDefaultAdapter())
            .registerTypeAdapter(Double::class.java, DoubleDefaultAdapter())
            .registerTypeAdapter(Long::class.java, LongDefaultAdapter())
            .registerTypeAdapter(String::class.java, StringNullAdapter())
            .registerTypeAdapterFactory(
                CollectionDefaultTypeAdapterFactory(
                    ConstructorConstructor(
                        HashMap()
                    )
                )
            )
            .registerTypeAdapterFactory(
                ReflectiveTypeAdapterFactory(
                    ConstructorConstructor(HashMap()),
                    FieldNamingPolicy.IDENTITY,
                    Excluder.DEFAULT
                )
            ).create()
    }
}